<?php

// +----------------------------------------------------------------------
// | 第三方支付
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2022 http://www.yicmf.com, All rights reserved.
// +----------------------------------------------------------------------
// | Author: 微尘 <yicmf@qq.com>
// +----------------------------------------------------------------------

namespace app\event\pay;


use alipay\Fund;
use alipay\Trade;
use app\common\event\Base;
use app\pay\model\Payment as PaymentModel;
use app\store\model\AfterSale as AfterSaleModel;
use app\store\model\Order as OrderModel;
use app\ucenter\event\UserAuth as UserAuthEvent;
use think\facade\Db;
use app\store\event\Order as OrderEvent;
use app\ucenter\model\User as UserModel;
use app\file\event\QrCode as QrCodeEvent;
use app\pay\event\UserBalance as UserBalanceEvent;
use app\pay\model\UserBalanceRecharge as UserBalanceRechargeModel;
use app\pay\event\PayOffline as PayOfflineEvent;
use app\pay\event\UserBalanceTransfer as UserBalanceTransferEvent;
use app\pay\model\Pay as PayModel;
use think\Exception;
use think\facade\Env;
use think\facade\Log;
use wechat\mch\Pay as WechatMchPay;

class PayTools extends Base
{

    /**
     * @var UserModel
     */
    protected $user = '';

    /**
     * @var array
     */
    protected $param = [];

    protected $result = ['code' => 0];

    /**
     * @var array|PayModel
     */
    protected $pay = '';
    protected $payment = '';
    /**
     * @var OrderModel
     */
    protected $order;



    public function appPay()
    {
        $config = $this->getAlipayConfig();
        $trace = Trade::instance($config);
        $subject = [
            'subject' => '支付订单',
            'out_trade_no' => time(),
            'total_amount' => 123,
        ];
        return $trace->appPay($subject);
    }

    /**
     * 主动查询支付状态
     * @param array $param
     * @return array
     * @author  : 微尘 <yicmf@qq.com>
     */
    public function query($param)
    {
        $this->param = $param;
        try {
            Db::startTrans();
            // 当前支付
            $this->pay = PayModel::where('pay_sn', $this->param['out_trade_no'])->find();
            if (!$this->pay)
            {
                throw new Exception('支付记录不存在');
            }
            if (1 == $this->pay['status'])
            {
                $this->result['code'] = 0;
                $this->result['message'] = '订单已经支付';
            }else {
                // 未支付订单，处理
                if ($this->_isAlipayOnline($this->pay['payment_code'])) {
                    // 支付宝支付
                    $this->_queryAlipay();
                } elseif ('wechat' == $this->pay['payment_code']) {
                    // 微信支付
                    $this->_queryWechat();
                } elseif (in_array($this->pay['payment_code'], ['alipay_offline', 'wechat_offline', 'qq_offline'])) {
                    // 离线支付
                    $this->pay['api_pay_no'] = $param['trade_no'];
                    $this->pay['api_amount'] = $param['pay_amount'];
                    $this->pay['api_buyer_id'] = $param['payment_qrcode_id'];
                    $this->pay['status'] = 1;
                    $this->pay->save();
                } else {
                    throw new Exception('支付方式不存在');
                }
                $this->_dealPay();

            }
            // 跳转详情
            Db::commit();
        } catch (Exception $e) {
            //                 回滚事务
            Db::rollback();
            $this->result['code'] = 1;
            $this->result['message'] = $e->getMessage();
        }
        return $this->result;
    }

    /**
     * 异步通知调用修改支付状态
     * @param array $param
     * @return array
     * @author  : 微尘 <yicmf@qq.com>
     */
    public function check($param)
    {
        $this->param = $param;
        try {
            Db::startTrans();
            // 当前支付
            $this->pay = PayModel::where('pay_sn', $this->param['out_trade_no'])->find();

            if (0 == $this->pay['status']) {
                // 未支付订单，处理
                if ($this->pay['payment_code'] == 'alipay') {
                    // 支付宝支付
                    $this->_dealPayAlipay($param);
                } elseif ('wechat' == $this->pay['payment_code']) {
                    $this->_dealPayWechat($param);
                    // 微信支付
                } elseif (in_array($this->pay['payment_code'], ['alipay_offline', 'wechat_offline', 'qq_offline'])) {
                    $this->pay['api_pay_no'] = $param['trade_no'];
                    $this->pay['api_amount'] = $param['pay_amount'];
                    $this->pay['api_buyer_id'] = $param['payment_qrcode_id'];
                    $this->pay['status'] = 1;
                    $this->pay->save();
                } else {
                    throw new Exception('支付方式不存在');
                }
                $this->_dealPay();

            } elseif (1 == $this->pay['status']) {
                $this->result['code'] = 0;
                $this->result['message'] = '订单已经支付';
            } else {
                $this->result['code'] = 1;
                $this->result['message'] = '订单未支付';
            }
            // 跳转详情
            Db::commit();
        } catch (Exception $e) {
            //                 回滚事务
            Db::rollback();
            $this->result['code'] = 1;
            $this->result['message'] = $e->getMessage();
        }
        return $this->result;
    }

    /**
     * 创建支付订单
     * @param array $param
     * @return mixed
     * @author  : 微尘 <yicmf@qq.com>
     */
    public function create($param)
    {
        $this->param = $param;
        try {
            Db::startTrans();
            $this->result['data']['is_redirect'] = 0;
            $this->_createCheck();
            $this->_createPay();
            $this->_createHandle();
            Db::commit();
            $this->result['code'] = 0;
            $this->result['data']['pay'] = $this->pay->visible(['id', 'qr_code', 'payment_code', 'total_amount', 'pay_sn'])->toArray();
        } catch (Exception $e) {
            Db::rollback();
            $this->result['code'] = 1;
            $this->result['line'] = $e->getLine();
            $this->result['file'] = $e->getFile();
            $this->result['message'] = $e->getMessage();
        }
        return $this->result;
    }


    /**
     * 获取支付信息
     * @param array $param
     * @param UserModel $user
     * @return mixed
     */
    public function pay($param, $user = null)
    {
        $this->param = $param;
        $this->user = $user;
        try {
            Db::startTrans();

            $this->pay = PayModel::where('pay_sn', $param['pay_sn'])->find();

            if (!$this->pay) {
                throw new Exception('系统异常，请稍候再试');
            }
            if (1 == $this->pay['status']) {
                throw new Exception('当前订单已经支付');
            }
//				if (0 != $this->pay['status']) {
//					throw new Exception('当前订单已经超时被取消');
//				}
            if (isset($param['payment_code']) && $param['payment_code'] != $this->pay['payment_code']) {
                // 更新支付方式
                $payment = PaymentModel::where('code', $param['payment_code'])->where('status', 1)->find();
                if (!$payment) {
                    throw new Exception('当前支付方式未开放');
                }
                $this->pay['payment_code'] = $payment['code'];
                $this->pay['payment_id'] = $payment['id'];
            }
            if (isset($param['repeat'])) {
                // 重新新增单号
                $pay = $this->pay->toArray();
                PayModel::where('id', $pay['id'])->update(['status' => -2]);
                unset($pay['id']);
                unset($pay['create_time']);
                $this->pay = PayModel::create($pay);
            }

            $this->result['data']['is_redirect'] = 0;
            $this->_createHandle();


            $this->pay->save();
            Db::commit();
            $this->result['code'] = 0;
            $this->result['data']['pay'] = $this->pay->visible(['id', 'qr_code', 'payment_code', 'total_amount', 'cny_amount', 'pay_sn'])->toArray();
        } catch (Exception $e) {
            //                 回滚事务
            Db::rollback();
            $this->result['code'] = 1;
            $this->result['message'] = $e->getMessage();
        }
        return $this->result;
    }


    /**
     * 微信转账
     * @param $out_biz_no
     * @param $payee_account
     * @param $amount
     * @param null $payee_real_name
     * @throws Exception
     */
    public function transferWechat($code, $out_biz_no, $open_id, $amount, $payee_real_name = null, $desc = null)
    {
        $param = [];
        $param['partner_trade_no'] = $out_biz_no;
        $param['openid'] = $open_id;
        $param['amount'] = $amount;
        $param['desc'] = $desc;
        $WechatMchPay = new WechatMchPay();
        $data = $WechatMchPay->transfers($param);
        if ('SUCCESS' !== $data['return_code'] || 'SUCCESS' !== $data['result_code']) {
            throw new Exception( $data['err_code_des']);
        }
        return $data;
    }

    /**
     * 转账提现
     * @param $out_biz_no
     * @param $payee_account
     * @param $amount
     * @param null $payee_real_name
     * @throws Exception
     */
    public function transfer($cash, $admin)
    {

        if ($this->_isAlipayOnline($cash['account_channel'])) {
            $result = $this->transferAlipay($cash['account_channel'], $cash['cash_sn'], $cash['account_no'], $cash['real_amount'], $cash['personal_name'], $cash['transfer_title']);
            $cash['api_pay_no'] = $result['order_id'];
        } else {
            // 微信
            $toOauth = $cash->user->oauths()->where('channel', 'wechat_lite')->find();
            $result = $this->transferWechat($cash['account_channel'], $cash['cash_sn'], $toOauth['open_id'], $cash['real_amount'] * 100, $cash['personal_name'], $cash['transfer_title']);
            $cash['api_pay_no'] = $result['payment_no'];
        }
        $cash['payment_time'] = time_format();
        return $cash;
    }

    /**
     * 转账到个人
     * @param $code
     * @param $out_biz_no
     * @param $payee_account
     * @param $amount
     * @param $payee_real_name
     * @param string $order_title
     * @return array
     */
    public function transferAlipay($code, $out_biz_no, $payee_account, $amount, $payee_real_name, $order_title = '转账'): array
    {
        $transfer = Fund::instance($this->getAlipayConfig($code));
        $result = $transfer->transUniTransfer($out_biz_no, $amount, $payee_account, $payee_real_name, $order_title);
        if ($result['code'] != 10000) {
            throw new Exception('支付宝转账失败，错误代码：' . $result['code'] . '，信息提示：' . $result['sub_msg']);
        }
        return $result;
    }


    /**
     * 退款
     * @param $pay
     * @return array
     */
    public function refund($pay)
    {
        try {
            $this->pay = $pay;
            if ($this->_isAlipayOnline($pay['payment_code'])) {
                $this->_alipayRefund($pay, $pay['total_amount']);
            } elseif ('balance' == $pay['payment_code']) {
                // 退回余额
                $this->_balanceRefund($pay, $pay['api_amount']);
            }

            $this->result['code'] = 0;
            $this->result['message'] = '退款成功';
        } catch (Exception $e) {
            $this->result['code'] = 1;
            $this->result['message'] = $e->getMessage();
        }
        return $this->result;
    }

    /**
     * 售后退款
     * @param PayModel $pay
     * @param AfterSaleModel $after
     * @return array
     */
    public function afterRefund($pay, $after)
    {
        try {
            if ($this->_isAlipayOnline($pay['payment_code'])) {

                // 根据汇率重算金额
                // TODO:扣除积分抵扣部分
                $amount = floor(100 * $pay['cny_amount'] * $after['amount'] / $pay['total_amount']) / 100;

                $this->_alipayRefund($pay, $amount, '售后退款退款');
            } elseif ('balance' == $pay['payment_code']) {
                // 退回余额
                $change = [];
                $change['relation_id'] = $pay['id'];
                $change['amount'] = $after['amount'];
                $change['change_code'] = 'after_sale_order';
                $change['message'] = '售后退款退款';
                UserBalanceEvent::change($change, $pay->user);
            }

            $pay['after_sale_amount'] = $after['amount'];
            if ($pay['after_sale_amount'] >= $pay['total_amount']) {
                $pay['status'] = -1;
            }
            $pay->save();
            $this->result['code'] = 0;
            $this->result['message'] = '退款成功';
        } catch (Exception $e) {
            $this->result['code'] = 1;
            $this->result['message'] = $e->getMessage();
        }
        return $this->result;
    }

    /**
     * 微信处理支付成功
     * @param $result
     * @return void
     * @throws Exception
     */
    protected function _dealPayWechat($result)
    {
        $this->pay['api_pay_no'] = $result['transaction_id'];
        $this->pay['api_buyer_id'] = $result['openid'];
        $this->pay['api_pay_status'] = $result['result_code'];
        $this->pay['api_amount'] = $result['total_fee'] / 100;
        $this->pay['appid'] = $result['appid'];
        $this->pay['status'] = 1;
        $this->pay->save();
    }

    /**
     * 支付宝处理支付成功
     * @param $result
     * @return void
     * @throws Exception
     */
    protected function _dealPayAlipay($result)
    {
        if ($result['code'] == 10000 && ($result['trade_status'] == 'TRADE_SUCCESS' || $result['trade_status'] == 'TRADE_FINISHED')) {
            if ($result['total_amount'] != $this->pay['cny_amount']) {
                Log::write('支付金额不符:'.$this->pay['id']);
//					throw new Exception('支付金额不符');
            }
            $this->pay['api_amount'] = $result['total_amount'];
            $this->pay['api_buyer_id'] = $result['buyer_user_id'] ?? '';
            $this->pay['api_buyer_name'] = $result['buyer_logon_id'] ?? '';
            $this->pay['api_pay_no'] = $result['trade_no'];
            $this->pay['api_pay_status'] = $result['trade_status'];
            $this->pay['status'] = 1;
            $this->pay->save();
        } else {
            throw new Exception('等待支付');
        }
    }

    protected function _queryAlipay()
    {
        $trace = Trade::instance($this->getAlipayConfig($this->pay['payment_code']));
        $result = $trace->query($this->pay['pay_sn']);
        $this->_dealPayAlipay($result);
    }


    /**
     * 微信支付
     * @throws Exception
     * @author 微尘 <yicmf@qq.com>
     */
    protected function _queryWechat()
    {
        throw new Exception('暂不支持');
    }


    /**
     * 支付安全验证
     * @throws Exception
     * @author  : 微尘 <yicmf@qq.com>
     */
    protected function _createCheck()
    {
        if (isset($this->param['type']) && 'recharge' == $this->param['type']) {

        } else {
            // 支付商品
            $this->order = OrderModel::where('status', 1)->where('order_sn', $this->param['order_sn'])->find();
            if (!$this->order) {
                throw new Exception('订单不存在!');
            }
            // 平台开启的支付方式
//				if (!in_array($this->order['payment']['code'], Config::get('pay.open_payment'))) {
//					throw new Exception('当前支付方式未开放');
//				}
        }

    }

    protected function _createPay()
    {
        if (isset($this->param['type']) && 'recharge' == $this->param['type']) {
            // 充值
            $recharge = UserBalanceRechargeModel::where('id', $this->param['recharge_id'])->find();
            if (!$recharge) {
                throw new Exception('充值请求不存在');
            }
            $pay = [];
            $pay['title'] = '在线充值';
            $pay['type'] = 'recharge';
            $pay['body'] = '';
            $pay['payment_code'] = 'wechat_lite';
            $pay['is_merge'] = 0;
            $pay['total_amount'] = $recharge['real_amount'];
            $pay['relation_id'] = $recharge['id'];
            $pay['status'] = 0;
            $pay['user_id'] = $recharge['user_id'];
            $pay['store_id'] = $recharge['store_id'];
            $this->pay = PayModel::create($pay);

        } else {
            // 过期支付信息需要删除
            $check = PayModel::where('relation_id', $this->order['id'])->where('status', 0)->find();
            if ($check) {
                PayModel::where('relation_id', $this->order['id'])->where('status', 0)->update(['status' => -2]);
            }
            $this->pay = self::precreate($this->model, 'order');
        }
    }

    /**
     * @param $model \think\Model
     * @param $type string
     * @return PayModel|\think\Model
     * @throws Exception
     */
    public static function precreate($model, $type = 'order')
    {

        if ($type == 'order') {
            $pay = [];
            $pay['payment_id'] = $model['payment_id'];
            $pay['payment_code'] = $model['payment']['code'];
            $pay['title'] = '源之味商城下单';
            $pay['body'] = '';
            $pay['total_amount'] = $model['pay_amount'];
            $pay['cny_amount'] = yen_to_cny( $model['pay_amount'] );
            $pay['dead_time'] = $model['limit_time'];
            $pay['status'] = 0;
            $pay['type'] = 'order';
            $pay['user_id'] = $model['user_id'];
            $pay['store_id'] = $model['store_id'];
            $pay['relation_id'] = $model['id'];
        } else {
            throw new Exception('预创建类型不支持');
        }

        $pay = PayModel::create($pay);
        if (!$pay) {
            throw new Exception('创建支付单异常');
        }
        return $pay;
    }

    /**
     * 合并支付
     * @param $pays array
     * @return PayModel|\think\Model
     * @throws Exception
     */
    public static function merge($pays, $type = 'order')
    {

        if ($type == 'order') {
            $insert = [];
            $insert['total_amount'] = 0;
            $insert['is_merge'] = 1;
            $insert['user_id'] = $pays[0]['user_id'];
            $insert['payment_code'] = $pays[0]['payment_code'];
            $insert['payment_id'] = $pays[0]['payment_id'];
            $insert['title'] = '合并订单支付';
            $insert['body'] = '';
            $insert['type'] = $type;
            $pay_ids = [];
            foreach ($pays as $pay) {
                $pay_ids[] = $pay['id'];
                $insert['total_amount'] += $pay['total_amount'];
                $insert['dead_time'] = $pay['dead_time'];
            }
            $insert['cny_amount'] = yen_to_cny($insert['total_amount']);
            $pay = PayModel::create($insert);
            PayModel::where('id', 'in', $pay_ids)->update(['parent_id' => $pay['id']]);
            return $pay;
        } else {
            throw new Exception('合并支付不支持当前类型');
        }
    }

    protected function _isAlipayOnline($payment_code)
    {
        return in_array($payment_code, ['alipay_web', 'alipay_wap', 'alipay_app', 'alipay_qrcode']);
    }

    protected function _balanceRefund($pay, $total_amount)
    {
        // 生成二维码
        $change = [];
        $change['relation_id'] = $pay['id'];
        $change['amount'] = $total_amount;
        $change['change_code'] = 'cancel_order';
        $change['message'] = '订单取消';
        UserBalanceEvent::change($change, $pay->user);

        $this->pay['api_pay_status'] = 'refund';
        $this->pay['status'] = -1;
        $this->pay->save();
    }


    /**
     * array(10) {
    ["code"] => string(5) "10000"
    ["msg"] => string(7) "Success"
    ["buyer_logon_id"] => string(14) "lil***@163.com"
    ["buyer_user_id"] => string(16) "2088002799574177"
    ["fund_change"] => string(1) "Y"
    ["gmt_refund_pay"] => string(19) "2022-05-25 09:05:36"
    ["out_trade_no"] => string(13) "6099632684218"
    ["refund_fee"] => string(4) "0.05"
    ["send_back_fee"] => string(4) "0.00"
    ["trade_no"] => string(28) "2022052422001474171404834702"
    }
     * @param $pay
     * @param $total_amount
     * @param $refund_reason
     * @param $out_request_no
     * @return void
     * @throws Exception
     */
    protected function _alipayRefund($pay, $total_amount, $refund_reason = '取消订单',$out_request_no=null)
    {
        $config = $this->getAlipayConfig($pay['payment_code']);
        $trace = Trade::instance($config);

        $subject = [
            'out_trade_no' => $pay['pay_sn'],
            'refund_amount' => $total_amount,
            'refund_reason' => $refund_reason,
            // 实现部分退款
//				'out_request_no'=>$pay['pay_sn'].'b'
        ];

        $result = $trace->refund($subject);

        if (10000 != $result['code'] || $result['fund_change'] !==  'Y')
        {
            // 退款异常
            throw new Exception($result['msg']);
        }
        $this->pay['refund_fee'] = $result['refund_fee'];
        if ($this->pay['refund_fee'] == $this->pay['api_amount'])
        {
            $this->pay['status'] = -1;
        }
    }


    /**
     * 创建支付
     */
    protected function _createHandle()
    {

//			$total_amount = $this->pay['total_amount'] < 1 ? 0.01 : round($this->pay['total_amount'] / 100, 2);
//		$total_amount = round($this->pay['cny_amount'] /10* pow(10, strlen((string)round($this->pay['cny_amount']))), 2);
        //	$total_amount = 0.01;
        $total_amount = round($this->pay['cny_amount'],2);
        if ($this->pay['payment_code'] == 'alipay_web') {
            $config = $this->getAlipayConfig($this->pay['payment_code']);
            if ($this->pay['type'] == 'recharge')
            {
                $config['return_url'] = (string)url('store/Account/walletlist',[],true,true) ;
            }else{
                if ($this->pay['is_merge'])
                {
                    $config['return_url'] = (string)url('/store/User/order',[],true,true) ;
                }else{
                    $config['return_url'] = (string)url('/store/Order/info',['id'=>$this->pay['relation_id']],true,true) ;
                }
            }
            $trace = Trade::instance($config);

            $subject = [
                'subject' => $this->pay['title'],
                'out_trade_no' => $this->pay['pay_sn'],
                'total_amount' => $total_amount,
//					'qr_pay_mode' => 3,
            ];

            $result = $trace->pagePay($subject);

            $this->pay['appid'] = $config['appid'];
//				$this->pay['qr_code'] = $result;
//				$this->pay['appid'] = $result['qr_code'];
            $this->pay->save();
            $this->result['code'] = 0;
            $this->result['data']['is_redirect'] = 1;
            $this->result['data']['redirect'] = '/pay/pr/' . $this->pay['pay_sn'];
            $this->result['data']['html'] = $result;
        } elseif ($this->pay['payment_code'] == 'alipay_app') {

            $config = $this->getAlipayConfig($this->pay['payment_code']);
            $trace = Trade::instance($config);
            $subject = [
                'subject' => $this->pay['title'],
                'out_trade_no' => $this->pay['pay_sn'],
                'total_amount' => $total_amount,
            ];
            $result = $trace->appPay($subject);
            $this->result['code'] = 0;
            $this->pay['appid'] = $config['appid'];
            $this->pay['qr_code'] = $result;
            $this->pay->save();
        }  elseif ($this->pay['payment_code'] == 'alipay_wap') {

            $config = $this->getAlipayConfig($this->pay['payment_code']);
            if ($this->pay['type'] == 'recharge')
            {
//					$config['return_url'] = (string)url('store/Account/walletlist',[],true,true) ;
                $config['return_url'] = $this->request->domain().'/h5/#/pages/account/bill?state=2' ;
            }else{
                if ($this->pay['is_merge'])
                {
                    $config['return_url'] = $this->request->domain().'/h5/#/pages/user/orders?type=2' ;
                }else{
                    $config['return_url'] = $this->request->domain().'/pages/order/detail?id='.$this->pay['relation_id'] ;
                }
            }
            $trace = Trade::instance($config);

            $subject = [
                'subject' => $this->pay['title'],
                'out_trade_no' => $this->pay['pay_sn'],
                'total_amount' => $total_amount,
            ];

            $result = $trace->wapPay($subject);
            $this->pay['appid'] = $config['appid'];
            $this->pay['qr_code'] = $result;
//				$this->pay['qr_code'] = $result;
//				$this->pay['appid'] = $result['qr_code'];
            $this->pay->save();
            $this->result['code'] = 0;
            $this->result['data']['is_redirect'] = 1;
            $this->result['data']['redirect'] = $this->request->domain().'/pay/pr/' . $this->pay['pay_sn'];
            $this->result['data']['html'] = $result;
        } elseif ($this->pay['payment_code'] == 'alipay_qrcode') {

            $config = $this->getAlipayConfig($this->pay['payment_code']);
            $trace = Trade::instance($config);
            $result = $trace->precreate($this->pay['title'], $this->pay['pay_sn'], $total_amount);
            if ($result['code'] != 10000) {
                throw new Exception($result['msg']);
            }
            $this->pay['appid'] = $config['appid'];
            $this->pay['qr_code'] = $result['qr_code'];
//				$this->pay['appid'] = $result['qr_code'];
            $this->pay->save();
            $this->result['code'] = 0;
            $this->result['data']['qr_code'] = $result['qr_code'];;
            $this->result['data']['qr_code_url'] = $this->request->domain() . QrCodeEvent::build($result['qr_code'], $this->pay['id'] . '.png', 'qrcode');
        } elseif ('balance' == $this->pay['payment_code']) {
            // 余额支付
            if ($this->user['pay_password'])
            {
                if (empty($this->param['pay_password']))
                {
                    throw new Exception('请输入支付密码');
                }
                if(true !== password_verify($this->param['pay_password'],$this->user['pay_password'])){
                    throw new Exception('支付密码验证失败');
                }
            }
            if ($this->user['balance'] < $this->pay['total_amount']) {
                // 余额不够
                throw new Exception('余额不足，请充值后再试');
            }
            $change = [];
            $change['relation_id'] = $this->pay['id'];
            $change['amount'] = -$this->pay['total_amount'];
            $change['change_code'] = 'pay_order';
            $change['message'] = $this->pay['title'];
            $log = UserBalanceEvent::change($change, $this->user);
            $this->_dealPay();
            $this->pay['api_pay_no'] = $log['id'];
            $this->pay['api_pay_status'] = 1;
            $this->pay['status'] = 1;
            $this->result['data']['is_redirect'] = 1;
            $this->result['data']['redirect'] = (string)url('store/user/order');
        } elseif ('alipay_offline' == $this->pay['payment_code']) {
            // 收款码
            $offline = new PayOfflineEvent();

            $param = [];
            $param['payment_code'] = $this->pay['payment_code'];
            $param['out_trade_no'] = $this->pay['pay_sn'];
            $param['order_amount'] = $this->pay['total_amount'];
            $param['title'] = $this->pay['title'];
            $param['body'] = $this->pay['body'];
            $param['pay_id'] = $this->pay['id'];
//				$param['notify_url'] = url('pay/notify/offline', [], true, true);
            if ('recharge' == $this->pay['type']) {
                $param['return_url'] = '';
            } else {
                $param['return_url'] = url('/order/detail', ['query' => $this->order['order_sn'], 'type' => 2], true, true);
            }
            $store = $this->pay->store()->find();
            $result = $offline->create($param, $store);
            if ($result['code'] != 0) {
                throw new Exception($result['message']);
            }
            $this->result['code'] = 0;
            $this->result['data']['redirect'] = $result['data']['url'];
            $this->result['data']['is_redirect'] = 1;
//				$this->pay['qr_code'] = $result['data']['qrcode_url'];;
            $this->pay->save();
        } else {
            // app支付
            $param['out_trade_no'] = $this->pay['pay_sn'];
            $param['trade_type'] = 'APP';
            $param['notify_url'] = url('pay/Wechat/notify', '', true, true);
            $param['total_fee'] = $this->pay['total_amount'] * 100;
            //  $param['total_fee'] = 1;
            $param['attach'] = $this->pay['type'];
            $param['detail'] = '';// 保留
            $param['body'] = '商品支付';
            $param['device_info'] = 'app';
            $WechatMchPay = new WechatMchPay();
            $pay_result = $WechatMchPay->unifiedorder($param);
            if ('fail' == strtolower($pay_result['return_code'])) {
                throw new Exception($pay_result['return_msg']);
            }
            if ('fail' == strtolower($pay_result['result_code'])) {
                throw new Exception($pay_result['err_code_des']);
            }
            $orderInfo = $WechatMchPay->appSign($pay_result['prepay_id'], $pay_result['nonce_str']);
            $this->result['data']['orderInfo'] = json_encode($orderInfo);
            $this->pay['qr_code'] = json_encode($orderInfo);

//				$this->result['param'] = $param;
//				$this->result['data'] = $data;
        }
    }

    protected function getAlipayConfig(): array
    {
        $config = [];


//        $c->gatewayUrl = "https://openapi.alipay.com/gateway.do";
//        $c->appId = "2021001103625089";
//        $c->rsaPrivateKey = 'MIIEpAIBAAKCAQEAplh7HUutY/Rl9sndseQPkKuAGr5EPZjL2UV/Z5tbQEM7ItwvPCLRU7rXqfyGu1KDTn7Sf9R7DyMVZNozb1b1aOlydHcTPhXAoHETmH641kaOpIt6K0KbXoWNkoaZVEZVlvzmXntzW4X7++FImIwyniBEKLoKu2Ryn2Xqq8+QSC/5Olr2PeyGOsUVQtTO+HAGjrKRXQy0Ha0xJdtX2XV7eAwaxAXaDikU+31lgRRk7cQYVSpXt17Oo1nSo6Tl30p5sgX7FOUZ4rGF7gSUXfXdtEDT1RGS4UPdLEyXMamLgw+tEkDHMxKbneCLolxYvw41q57t2ojrXp7UBKVBruqbrwIDAQABAoIBAFFwHg4Qn7nAzC6PU7cktS4ZmGT/Y39Yj+w2JxK9L2Z9w7TkYUeqsBqy7aSuGfQZiGlkk3+7seeOQIoYfXfz9b/AEqXMKiKKGb0yvuo4mBtnfaw3EL+fI1uaPN5QgT6OFJcQB2SYQbi8FsqQ166/bISXvWbG9jwaCDfbeJFW1AdSkHa5tEWbnPxbQPaNZhhH2EVVqbd5zFwqmPKIDrPcfIDSX27ssatm8bIV52WAiufVVyN09QaQzKKbkTAG42WXnCVYPRQt707WPGKaQYqLvSqQsSXeNW9KWSdwtDG0UC8TEKjn+4EROCGmgrnajand9q5QGuGxWLqejaHZAgwQG1ECgYEA84au0R1BKCnUdQM8p4i1V88p7ZSwxAMEz44LENUG44GQoIkVeUIc+H8QgDCh4WYcTqtEinnSN6Q7LUEqKTwySr1oT9/FwdRzro/tlgfs4z1RvgFhPGrRelwHc5Z4r8sLMxekYUMV/29uAVXSFbInoHQVXQ4wTtJPY3abhc+vaVkCgYEArt2+S/1pdztIFED60qHcTQfCKJjE+OOatGNYTFkJqrHRVdo8Hb4OOZGMaH+gYXUYQdmcM4xpwLTeCQkFPNIdD4DhV3VoVpLKBOdkWM0l/+VOTn7zeBDALQGUigLMsXfLSVktuIyzYQcRH7027VjADoxm0wgrXkor9sFSGDG3BEcCgYB5dNzPstWCYIpz6a9gp1A6gToaIiSfPhoyIlfmhziuUzp8tqIdHhow3b6vEJJMRo8rtUO0BNoRojlZcrzCYCF9IUZbP/HzoDAqCeKnB0DgfP690xZZ+bSMYEXfIlcC5jOpwcrcL4dTJJIq3FCxPW+CGSNmi+MQDNhHdSpP7KtB0QKBgQCgAcdfQUKAF36dCdh5ZCJxWegPvbp/A8VLypvBQLfXuV4TcN4RWRcrFkOkWyQmCT9pAfYsNQ+PhfCl09s3DAwLY6LOpGAU17yDQDhSCWX8AZblvMSL2MgAZrHEl0s2GKerNi7f798zqYPBxyG7jLowlciA0bjdToFsCPlVqigNgQKBgQCkWPxIY1UPGsIhqW5XLdacq0oRxc1RjGOvYBSQeXZNvlt6BnBoew+OicYanFGL0G8unN/8g7BElJsyMhnasXqdH0GDNx3tE+8/BvcKRObkwBli0g7e4a9xtetlqPYr8E8fZmzX2vJPe2hNdgpERoeMMKAhFrBrqLaEbFBV6d/9Gw==';
//        $c->format = "json";
//        $c->charset= "UTF-8";
//        $c->signType= "RSA2";


        // 应用ID
        $config['appid'] = '2021004181661289';
        // 应用私钥文字内容 (1行填写)
        $config['private_key'] = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCbZ2SIsbDCutaxmt12iWQhKf1szMH9/jhEZAL2Z96HfPLZv6+vRoYyDd97yhnG6rRpI7nB7ABgv+8dtjcNyVp6HlMnvKvHxx9lJAaQ8+wPcVW2GQlZ5+k+kC8hac1SPxXtWb44qZy9jxW5rrBnw/sE+US9+wKHnt7sUJrISu9wnTtOADXtXQEgUUV6rYar/gJ3XcR5oBbWkgt/mQX2ffm3Ks8XedCdBe3T+5umXQ5QhG3hjh9ktSQ/+8afqD38OQdD6oVat/Taa0vPouHh9QP1XHjHcq3/QiyF1cza+D7KJ1iUcnVnDbSfL5PuCJOME4EpfEFUzcFwuXstnCadgKBxAgMBAAECggEAMA9tvAiYDeESfKLUUtBysv71bSx14kM4y43SjLnazDQMNuNdReudnOVFdFcwWaBEYy+1Rw/hngo9vQaZSB45aQLv3J4w0fv27aSSk0mce7olM8fSaIecTsjwinjaEtGHynuypHtwCf+yTFaGH9EwVH1ykP6L7b1oW9UhyUfDfSPlHGBsNJhGaGyZwtOQzz8Q3z2N1MhibgnE1xmNo/1mKXnfPulckaDV11p8Fwod221qOmULzkPzGFbQIS0haeP2P68YLGLFdn4g9WTQZHxbmKM6L6VIAo0hh8En1rvMmDi7zIjVVxWbzaGi10cM5Ex5dQB1tnpNgYninZ+t4D/JQQKBgQD10D4UIvd+w0zjjhs1UCvNWIQMKkHq3PojEiOq5fMtZ7QEU9E7CXyMRufNhBsyW0A9lu+EFCuBpCSjhKZsZJXZInBoDjHp6GUTAGP4HY6QEwoLrWzt0rpuysxyuQEqNFkcJWBUouXjTZ3zpt7KgYcBSCJaBom9xy4N7mJlkPUl3QKBgQCh2AYHDRSvXtk1Uc2JDM4DOaXEz2pohX0yB1I7nqzsqMnKzg8APjxw9U1boSSlRc8oDwL31LV40pVMvJBPtchDJx5d0sbKNaEU8bsGjIMmEOtF6PiraT6VMzJhw1cVJALUiuankAdyS2MJtTqbeknWaFMMdBtxze3LBhsK3S8NpQKBgEBodBuqndblLXxie9aYTyHbE55sZCE6DYCq/BWHcxRum8iWfbhOYAgRfCNpfgbPyiFZLyEYd93cOI1v8HtuT6U5VOKu9X0om3NDIu6cMAKoOnWc13HpSVhGYxOcTiXU2ZR6ZqdGl53bdIunKbE+BzXaxMV5+RV03yhfUgDy3okxAoGAaS255RU0LzBl2sf52ipPLDtnprrhPWIbVcr6PzLE0Nx0n+9AQnkv0H0qs/TKmvn+QdtXo3ZCJW49huw4oQTTTAj9LB5SAJHPyIu8buocRT3TmNBp4wP3nwDxqiVHz75idHx8n8Lzg+zIRUPY/bgAim2sIzjFqTUaZ8nlAy9xZ90CgYEAjPseDQE57ZD7qG1krSQIUWCtILWMoDRRbIqFyIvtTkRebeQZDtWgdz9gGkVXbI8I+Q2brPDlBncRpckHsq3KjbpiMMQSYv/AwOwuB6BICFYv0rKKcEx1L5wn8kmBsJ4UENdAYzqxMm57CD7M8VtCl7KCyfXAs93IeP3q2KhMnlY=';
        // 支付宝公钥
        $config['alipay_public_path'] = realpath(app()->getRootPath() . 'data/alipay/alipayCertPublicKey_RSA2.crt');
        //应用公钥证书完整内容（新版资金类接口转 app_cert_sn）
        $config['app_public_path'] = realpath(app()->getRootPath() . 'data/alipay/appCertPublicKey_' . $config['appid'] . '.crt');
        //应用公钥证书完整内容（新版资金类接口转 app_cert_sn）
        $config['alipay_root_path'] = realpath(app()->getRootPath() . 'data/alipay/alipayRootCert.crt');
        // 支付成功通知地址

        $config['notify_url'] =  (string)url('api/service.Pay/alipay',[],false,true) ;
        // 网页支付回跳地址
        // 蚂蚁统一会员 ID。必须等于请求发起方的 pid 示例2088301409188095
        $config['pid'] = '';
        return $config;
    }

    /**
     * 调用处理结果
     * @throws Exception
     */
    protected function _dealPay()
    {

        if ('order' == $this->pay['type']) {
            $event = new OrderEvent();
            if (1 == $this->pay['is_merge']) {
                // 合并支付，查询分单
                $pays = PayModel::where('parent_id', $this->pay['id'])
                    ->where('type', $this->pay['type'])
                    ->where('status', '<', 1)
                    ->select();
                foreach ($pays as $pay) {
                    $pay['api_pay_no'] = $this->pay['api_pay_no'];
                    $pay['api_buyer_id'] = $this->pay['api_buyer_id'];
                    $pay['api_pay_status'] = $this->pay['api_pay_status'];
                    $pay['api_amount'] = $this->pay['api_amount'];
                    $pay['buyer_user_id'] = $this->pay['buyer_user_id'];
                    $pay['appid'] = $this->pay['appid'];
                    $pay['status'] = 1;
                    $pay->save();
                    $event->pay($pay);
                }
            } else {
                $event->pay($this->pay);
            }
        } elseif ('auth' == $this->pay['type']) {
            $auth = new UserAuthEvent();
            $auth->pay($this->pay);
        } elseif ('bill' == $this->pay['type']) {
//				$auth = new ChargeBillEvent();
//				$auth->pay($this->pay);
        } elseif ('transfer' == $this->pay['type']) {
            $auth = new UserBalanceTransferEvent();
            $auth->pay($this->pay);
        } else {
            // 充值
            $event = new UserBalanceEvent();
            $event->pay($this->pay);
        }


    }
}
